﻿using LibreHardwareMonitor.Hardware;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FanMotionWink
{

    public class FanUtils
    {
        public class FansItemModel
        {
            IControl control;
            ISensor sensor;
            List<TemperatureItemModel> temperautreList;
            public FansItemModel(ISensor sensor, IControl control, List<TemperatureItemModel> temperautreList)
            {
                this.sensor = sensor;
                this.control = control;
                this.temperautreList = temperautreList;
                // init read config 读取初始配置
                this._selectedInputTemplateIdString = LinkedData.TemperaureSrcId;
            }
            public void UpdateControlValue(float input)
            {
                this.control.SetSoftware(input);
            }

            public StorageInstance.FanController LinkedData => StorageInstance.Instance.FindOrCreate(this.Id);

            public bool IsInControl
            {
                get => LinkedData?.IsControl ?? false;
                set
                {
                    if (LinkedData == null)
                    {
                        return;
                    }
                    LinkedData.IsControl = value;
                    StorageInstance.RefreshSave();
                }
            }



            public string SelectedControllerWays
            {
                set { Console.WriteLine(value); }
            }

            public string _selectedInputTemplateIdString;
            public string SelectedInputTemplateIdString
            {
                get { return _selectedInputTemplateIdString; }
                set
                {
                    _selectedInputTemplateIdString = value;
                }
            }

            public float TempatureValNow => FanUtils.GetTempatureList().FirstOrDefault(item => item.Id == _selectedInputTemplateIdString)?.Val ?? 0;

            public string Id
            {
                get => this.sensor.Identifier.ToString();
            }

            public string Name
            {
                get => this.sensor.Name;
            }
            public string DetailDesc
            {
                get => this.sensor.Value + " RPM ";
            }
            public string ControlMode
            {
                get => $"{this.control.ControlMode} {this.control.SoftwareValue}";
            }

            public float ControlValue
            {
                get => this.control?.Sensor?.Value ?? 0.0f;
            }
            public float ControlValueMin
            {
                get => this.control?.MinSoftwareValue ?? 0.0f;
            }
            public float ControlValueMax
            {
                get => this.control?.MaxSoftwareValue ?? 0.0f;
            }


        }

        public class TemperatureItemModel
        {
            private ISensor sensor;

            public TemperatureItemModel(ISensor sensor)
            {
                this.sensor = sensor;
            }

            public string Id
            {
                get => this.sensor.Identifier.ToString();
            }
            public string Name
            {
                get => this.sensor.Name;
            }
            public string Desc
            {
                get => $"{this.sensor.Value ?? 0:.0}℃ - {this.sensor.Name}";
            }
            public float Val
            {
                get => this.sensor.Value ?? 0;
            }
        }

        static void hwGetTempatureSingle(IHardware hardware, List<TemperatureItemModel> storageList)
        {
            foreach (ISensor sensor in hardware.Sensors)
            {
                if (sensor.SensorType == SensorType.Temperature)
                {
                    storageList.Add(new TemperatureItemModel(sensor));
                }
            }
            foreach (IHardware subhardware in hardware.SubHardware)
            {
                hwGetTempatureSingle(subhardware, storageList);
            }
        }

        public static List<TemperatureItemModel> GetTempatureList()
        {
            var computer = HardwareUtils.Computer;
            List<TemperatureItemModel> temperautreList = new List<TemperatureItemModel>();
            foreach (IHardware hardware in computer.Hardware)
            {
                hwGetTempatureSingle(hardware, temperautreList);
            }
            return temperautreList;
        }

        public static List<FansItemModel> GetFanItemModelList()
        {
            List<FansItemModel> fanList = new List<FansItemModel>();
            var computer = HardwareUtils.Computer;

            var temperautreList = GetTempatureList();

            foreach (IHardware hardware in computer.Hardware)
            {
                Dictionary<string, ISensor> fanDict = new Dictionary<string, ISensor>();
                Dictionary<string, IControl> controllerDict = new Dictionary<string, IControl>();

                foreach (IHardware subhardware in hardware.SubHardware)
                {

                    foreach (ISensor sensor in subhardware.Sensors)
                    {
                        if (sensor.SensorType == SensorType.Fan)
                        {
                            fanDict.Add(sensor.Identifier.ToString(), sensor);
                        }
                        else if (sensor.SensorType == SensorType.Control)
                        {
                            var control = sensor.Control as IControl;
                            if (control != null)
                            {
                                controllerDict.Add(sensor.Identifier.ToString(), control);
                            }
                        }
                    }
                }

                // 找到 fan 对应的 control
                foreach (var kv in fanDict)
                {
                    var sensorId = kv.Key;
                    var sensor = kv.Value;
                    var controleId = sensorId.Replace("/fan/", "/control/");
                    controllerDict.TryGetValue(controleId, out var ctrler);
                    if (ctrler != null)
                    {
                        fanList.Add(new FansItemModel(sensor, ctrler, temperautreList));
                    }
                }
            }

            return fanList;
        }



        public static void InitUpdateInterval()
        {
            // 启动定时器
            new Thread(new ThreadStart(() =>
            {
                while (true)
                {
                    Thread.Sleep(1000);
                    if (!StorageInstance.Instance.GlobalEnable)
                        continue;

                    // 定时处理
                    var tlist = GetFanItemModelList();

                    foreach (var item in tlist)
                    {
                        var kitem = StorageInstance.Instance.FindOrCreate(item.Id);
                        if (!kitem.IsControl)
                        {
                            continue;
                        }
                        var kk = kitem.curvePoints.CalcYPosWithX(item.TempatureValNow);
                        if (kk != null)
                        {
                            item.UpdateControlValue(kk.Value);
                        }
                    }
                }
            })).Start();
        }

    }
}
